package com.smartcruise.service;

import android.content.Context;
import android.util.Log;

import com.amap.api.location.AMapLocation;
import com.amap.api.location.AMapLocationClient;
import com.amap.api.location.AMapLocationClientOption;
import com.amap.api.location.AMapLocationListener;
import com.amap.api.maps.AMapUtils;
import com.amap.api.maps.model.LatLng;

import java.util.ArrayList;
import java.util.List;

/**
 * Created by FengChaoQun
 * on 2018/2/4 0004
 * 定位管理
 */

public class LocationManager implements AMapLocationListener {

    private List<OnLocationChange> onLocationChanges = new ArrayList<>();
    private AMapLocation lastData;

    //声明mLocationClient对象
    public AMapLocationClient mLocationClient;
    //声明mLocationOption对象
    public AMapLocationClientOption mLocationOption = null;
    //定位时间间隔
    private final static int interval = 10 * 1000;
    //默认上传位置的时间间隔 即使位置没有任何变化 达到改时间也需要上传
    public final static int default_interval = 5 * 60 * 1000;
    //两点之间最低的距离 超过这个距离的位置应该上报
    public final static int minDistance = 20;

    public static LocationManager getInstance() {
        return LocationManager.SingletonHolder.myHandler;
    }

    private static class SingletonHolder {
        private static final LocationManager myHandler = new LocationManager();
    }

    private LocationManager() {

    }

    public void init(Context context) {
        mLocationClient = new AMapLocationClient(context);
        //初始化定位参数
        mLocationOption = new AMapLocationClientOption();
        //设置定位监听
        mLocationClient.setLocationListener(this);
        //设置定位模式为高精度模式，Battery_Saving为低功耗模式，Device_Sensors是仅设备模式
        mLocationOption.setLocationMode(AMapLocationClientOption.AMapLocationMode.Hight_Accuracy);
        //设置定位间隔,单位毫秒,默认为2000ms
        mLocationOption.setInterval(interval);
        //是否开启设备传感器，当设置为true时，网络定位可以返回海拔、角度和速度。
        mLocationOption.setSensorEnable(false);//这里是长期定位。考虑到节能，不开启
        //设置定位参数
        mLocationClient.setLocationOption(mLocationOption);
    }

    public void startLocating() {
        if (mLocationClient != null && !mLocationClient.isStarted()) {
            // 在定位结束后，在合适的生命周期调用onDestroy()方法
            mLocationClient.startLocation();
        }
    }

    public void endLocating() {
        if (mLocationClient != null && mLocationClient.isStarted()) {
            mLocationClient.onDestroy();
        }
    }

    public void registerObserver(OnLocationChange onLocationChange) {
        if (onLocationChange != null && !onLocationChanges.contains(onLocationChange)) {
            onLocationChanges.add(onLocationChange);
        }
    }

    public void removeObserver(OnLocationChange onLocationChange) {
        if (onLocationChange != null) {
            onLocationChanges.remove(onLocationChange);
        }
    }

    public AMapLocation getLastData() {
        return this.lastData;
    }

    private void onNewLocatingChange(AMapLocation aMapLocation) {
        //偶尔会出现收到坐标为0.0的情况 在这里过滤掉这种数据
        if (aMapLocation != null && aMapLocation.getLatitude() == 0 && aMapLocation.getLongitude() == 0) {
            return;
        }
        this.lastData = aMapLocation;
        for (OnLocationChange onLocationChange : onLocationChanges) {
            onLocationChange.onChange(aMapLocation);
        }
    }

    public interface OnLocationChange {
        void onChange(AMapLocation aMapLocation);
    }

    @Override
    public void onLocationChanged(AMapLocation aMapLocation) {
        if (aMapLocation != null) {
            if (aMapLocation.getErrorCode() == 0) {
                onNewLocatingChange(aMapLocation);
            } else {
                //显示错误信息ErrCode是错误码，errInfo是错误信息，详见错误码表。
                Log.e("LocationManager", "location Error, ErrCode:"
                        + aMapLocation.getErrorCode() + ", errInfo:"
                        + aMapLocation.getErrorInfo());
            }
        }
    }


    /**
     * 获取两个经纬坐标之间的距离
     *
     * @param lat1 1点的纬度
     * @param lng1 1点的经度
     * @param lat2 2点的纬度
     * @param lng2 2点的经度
     * @return 距离 单位 米
     */
    public static float getDistance(double lat1, double lng1, double lat2, double lng2) {
        return AMapUtils.calculateLineDistance(new LatLng(lat1, lng1), new LatLng(lat2, lng2));
    }

}
